package com.meiyuetao.myt.job;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import lab.s2jh.auth.dao.UserR2RoleDao;
import lab.s2jh.auth.entity.Role;
import lab.s2jh.auth.entity.User;
import lab.s2jh.auth.entity.UserR2Role;
import lab.s2jh.auth.service.RoleService;
import lab.s2jh.auth.service.UserService;
import lab.s2jh.ctx.DynamicConfigService;
import lab.s2jh.schedule.BaseQuartzJobBean;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.collect.Lists;
import com.meiyuetao.myt.md.dao.PersonalMessageDao;
import com.meiyuetao.myt.md.dao.PersonalMessageItemDao;
import com.meiyuetao.myt.md.entity.PersonalMessage;
import com.meiyuetao.myt.md.entity.PersonalMessageItem;
import com.meiyuetao.myt.sale.entity.BoxOrder.BoxOrderStatusEnum;
import com.meiyuetao.myt.sale.service.BoxOrderService;
import com.taobao.api.ApiException;
import com.taobao.api.DefaultTaobaoClient;
import com.taobao.api.TaobaoClient;
import com.taobao.api.domain.Trade;
import com.taobao.api.request.TradeFullinfoGetRequest;
import com.taobao.api.request.TradesSoldGetRequest;
import com.taobao.api.response.TradeFullinfoGetResponse;
import com.taobao.api.response.TradesSoldGetResponse;

/**
 * 一般只执行一次，用于首次从Tmall拉取最近3个月订单
 * 
 * @author jee
 * 
 */
public class IybAutoImportTmallOrderJob extends BaseQuartzJobBean {
    private static Logger logger = LoggerFactory.getLogger(IybAutoImportTmallOrderJob.class);

    protected static String defaultUrl = "http://gw.api.taobao.com/router/rest";// 真实环境
    protected static String appkey = "21816289";
    protected static String secret = "a639af114ff916cdde57bbbc79184221";
    // protected static String sessionKey =
    // "6100920c138bba90838fe871a2f61b86b51cac88e390a7d841787243";

    protected String sessionKey;

    private Map<String, BoxOrderStatusEnum> map = new HashMap<String, BoxOrderStatusEnum>() {
        {
            /**
             * 淘宝交易状态 TRADE_NO_CREATE_PAY(没有创建支付宝交易) WAIT_BUYER_PAY(等待买家付款)
             * WAIT_SELLER_SEND_GOODS(等待卖家发货,即:买家已付款)
             * WAIT_BUYER_CONFIRM_GOODS(等待买家确认收货,即:卖家已发货)
             * TRADE_BUYER_SIGNED(买家已签收,货到付款专用) TRADE_FINISHED(交易成功)
             * TRADE_CLOSED(付款以后用户退款成功，交易自动关闭)
             * TRADE_CLOSED_BY_TAOBAO(付款以前，卖家或买家主动关闭交易)
             * PAY_PENDING(国际信用卡支付付款确认中)
             */
            put("TRADE_NO_CREATE_PAY", BoxOrderStatusEnum.S10O);
            put("WAIT_BUYER_PAY", BoxOrderStatusEnum.S10O);
            put("WAIT_SELLER_SEND_GOODS", BoxOrderStatusEnum.S20PYD);
            put("WAIT_BUYER_CONFIRM_GOODS", BoxOrderStatusEnum.S50DF);
            put("TRADE_BUYER_SIGNED", BoxOrderStatusEnum.S60R);
            put("TRADE_FINISHED", BoxOrderStatusEnum.S70CLS);
            put("TRADE_CLOSED", BoxOrderStatusEnum.S70CLS);
            put("TRADE_CLOSED_BY_TAOBAO", BoxOrderStatusEnum.S90CANCLE);
            put("PAY_PENDING", BoxOrderStatusEnum.S10O);
        }
    };

    /**
     * 一般只在初始化时执行一次，用于一次性从Tmall拉取最近3个月订单
     * 
     * 后续新增/修改的订单用 @see IybAutoIncrementImportTmallOrderJob 拉取
     */
    protected void executeInternalBiz(JobExecutionContext context) {
        BoxOrderService boxOrderService = this.getSpringBean(BoxOrderService.class);
        DynamicConfigService dynamicConfigService = this.getSpringBean(DynamicConfigService.class);

        /*
         * sessionKey有可能失效，所以写入配置文件，当失效时重新授权获取sessionKey设置系统参数即可 sessionKey获取：访问
         * https
         * ://oauth.taobao.com/authorize?client_id=21816289&response_type=token
         * 点击授权即可获取 SessionKey / accessToken 具体参考
         * http://open.taobao.com/doc/detail
         * .htm?spm=a219a.7386781.0.0.MIjx15&id=118
         */
        sessionKey = dynamicConfigService.getString("cfg.tmall.api.sessionkey", "6100920c138bba90838fe871a2f61b86b51cac88e390a7d841787243");

        List<Trade> trades;
        try {
            trades = getTrades();
        } catch (ApiException e) {
            // 控制台打印错误信息
            e.printStackTrace();
            // 定时任务执行记录显示错误信息
            context.setResult(e.getErrCode() + ":" + e.getErrMsg());
            // 给指定用户发送消息，提示出错
            sendTip("从Tmall更新订单失败！", e.getErrCode() + ":" + e.getErrMsg());
            // 系统日志记录错误信息
            logger.warn("从Tmall更新订单失败！" + e.getErrCode() + ":" + e.getErrMsg());
            return;
        }
        if (CollectionUtils.isNotEmpty(trades)) {
            String result = boxOrderService.importOrderFromTmall(trades, map);
            context.setResult(result);
            logger.info("从天猫拉取订单" + trades.size() + "条");
        }
    }

    /**
     * 获取所有订单数据 , 默认最近三个月
     * 
     * @return
     * @throws ApiException
     */
    private List<Trade> getTrades() throws ApiException {
        TaobaoClient client = new DefaultTaobaoClient(defaultUrl, appkey, secret);
        TradesSoldGetRequest req = new TradesSoldGetRequest();
        Long pageNo = 1L;
        req.setFields("tid");
        req.setPageNo(pageNo);
        req.setPageSize(99L);
        // 循环获取所有订单ID(tid)
        List<Trade> tidList = Lists.newArrayList();
        while (true) {
            req.setPageNo(pageNo++);
            TradesSoldGetResponse response = client.execute(req, sessionKey);
            String errCode = response.getErrorCode();
            if (StringUtils.isNotBlank(errCode)) {
                if (errCode.equals("27")) {
                    sendTip("从天猫拉取订单失败", "错误编号：" + errCode + ",Session已过有效期（" + response.getMsg() + "）");
                } else {
                    sendTip("从天猫拉取订单失败", "错误编号：" + errCode + "," + response.getMsg());
                }
            }
            List<Trade> result = response.getTrades();
            if (CollectionUtils.isEmpty(result)) {
                break;
            }
            tidList.addAll(result);
        }

        // 循环根据订单ID 获取订单所有详细信息
        List<Trade> trades = Lists.newArrayList();
        for (Trade trade : tidList) {
            trades.add(getTrade(trade.getTid()));
        }
        return trades;
    }

    /**
     * 获取订单详细数据，根据tid
     * 
     * @param tid
     *            订单ID or 交易ID
     * @return
     * @throws ApiException
     */
    private Trade getTrade(Long tid) throws ApiException {
        TaobaoClient client = new DefaultTaobaoClient(defaultUrl, appkey, secret);
        TradeFullinfoGetRequest req = new TradeFullinfoGetRequest();
        req.setFields("seller_nick, buyer_nick, title, type, created, tid, seller_rate,buyer_flag, buyer_rate, "
                + "status, payment, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, "
                + "buyer_obtain_point_fee, point_fee, real_point_fee, received_payment, commission_fee, buyer_memo, "
                + "seller_memo, alipay_no, alipay_id,buyer_message, pic_path, num_iid, num, price, buyer_alipay_no, "
                + "receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, "
                + "receiver_mobile, receiver_phone,seller_flag, seller_alipay_no, seller_mobile, seller_phone, seller_name, "
                + "seller_email, available_confirm_fee, has_post_fee, timeout_action_time, snapshot_url, cod_fee, cod_status, "
                + "shipping_type, trade_memo, is_3D,buyer_email,buyer_area, trade_from, is_lgtype, is_force_wlb, is_brand_sale, "
                + "buyer_cod_fee, discount_fee, seller_cod_fee, express_agency_fee, invoice_name, service_orders, credit_cardfee, "
                + "step_trade_status, step_paid_fee, mark_desc, has_yfx, yfx_fee, yfx_id, yfx_type, trade_source, eticket_ext, send_time, "
                + "is_daixiao, is_part_consign, arrive_interval, arrive_cut_time, consign_interval, zero_purchase, orders, promotion_details, "
                + "invoice_name, orders.is_www, orders.store_code, service_tags");
        req.setTid(tid);
        TradeFullinfoGetResponse response = client.execute(req, sessionKey);
        return response.getTrade();
    }

    private void sendTip(String title, String content) {
        PersonalMessageDao personalMessageDao = this.getSpringBean(PersonalMessageDao.class);
        UserService userService = this.getSpringBean(UserService.class);
        RoleService roleService = this.getSpringBean(RoleService.class);
        UserR2RoleDao userR2RoleDao = this.getSpringBean(UserR2RoleDao.class);
        PersonalMessageItemDao personalMessageItemDao = this.getSpringBean(PersonalMessageItemDao.class);

        PersonalMessage personalMessage = new PersonalMessage();
        personalMessage.setTitle(title);
        personalMessage.setContents(content);
        User user = userService.findByProperty("signinid", "admin");
        personalMessage.setPublishUser(user);
        personalMessage.setPublishTime(new Date());
        personalMessageDao.save(personalMessage);

        Role role = roleService.findByProperty("code", "ROLE_OP_MGR");// 运维主管（接收所有提醒）
        if (role != null) {
            personalMessageDao.save(personalMessage);
            List<UserR2Role> userR2Roles = userR2RoleDao.findByRole_Id(role.getId());
            for (UserR2Role item : userR2Roles) {
                PersonalMessageItem personalMessageItem = new PersonalMessageItem();
                personalMessageItem.setPersonalMessage(personalMessage);
                personalMessageItem.setTargetUser(item.getUser());
                personalMessageItemDao.save(personalMessageItem);
            }
        }
    }
}